package com.alibaba.citrus.cr.mn.order.center.facade.function.check;

import com.alibaba.citrus.cr.common.enums.ordercenter.*;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.AssertUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.JsonUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.MoneyUtils;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.BaseDataServiceAdapter;
import com.epoch.app.mnordercenter.model.dto.DictionaryResponse;
import com.epoch.app.mnordercenter.model.dto.ExchangeOrderAtomCreateRequest;
import com.epoch.app.mnordercenter.model.dto.ExchangeOrderLineAtomCreateRequest;
import com.epoch.app.mnordercenter.model.dto.SalesOrderAtomCreateLineRequest;
import com.epoch.app.mnordercenter.orderbaserequest.OrderAtomCreateResponse;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author dongju
 * @ClassName ExchangeOrderCreateParamsCheck
 */
@Service
public class ExchangeOrderCreateParamsCheck extends AbstractOrderParamsCheckService<ExchangeOrderAtomCreateRequest, OrderAtomCreateResponse> {

    @Resource
    private BaseDataServiceAdapter baseDataServiceAdapter;
    @Override
    public void paramsEnumDictCheck(List<ExchangeOrderAtomCreateRequest> requestList, List<OrderAtomCreateResponse> responseList) {

        // 系统来源
        List<DictionaryResponse> fromSysResponseList = baseDataServiceAdapter.queryDictionarys(DictionaryTypeEnum.FROM_SYS.getCode());
        Map<String, DictionaryResponse> fromSysMap = fromSysResponseList.stream().collect(Collectors.toMap(DictionaryResponse::getCode, Function.identity(), (k1, k2) -> k2));
        //业态
        List<DictionaryResponse> businessTypeResponseList = baseDataServiceAdapter.queryDictionarys(DictionaryTypeEnum.BUSINESS_TYPE.getCode());
        Map<String, DictionaryResponse> businessTypeMap = businessTypeResponseList.stream().collect(Collectors.toMap(DictionaryResponse::getCode, Function.identity(), (k1, k2) -> k2));
        // 业务单元编码
        List<DictionaryResponse> businessUnitCodeResponseList = baseDataServiceAdapter.queryDictionarys(DictionaryTypeEnum.BUSINESS_UNIT_CODE.getCode());
        Map<String, DictionaryResponse> businessUnitCodeMap = businessUnitCodeResponseList.stream().collect(Collectors.toMap(DictionaryResponse::getCode, Function.identity(), (k1, k2) -> k2));


        requestList.forEach(t -> {

            if (fromSysMap.get(t.getFromSys()) == null) {
                throw new FunctionException("OC-01-001-01-15-006", "来源系统编码");
            }
            DictionaryResponse dictionaryResponse = businessTypeMap.get(t.getBusinessType());
            if (dictionaryResponse == null) {
                throw new FunctionException("OC-01-001-01-15-006", "业态编码");
            }
            DictionaryResponse dicResponse = businessUnitCodeMap.get(t.getBusinessUnitCode());
            if (dicResponse == null) {
                throw new FunctionException("OC-01-001-01-15-006", "业务单元编码");
            }
            // 覆盖用户传入数据
            t.setBusinessTypeName(dictionaryResponse.getName());
            t.setBusinessUnitName(dicResponse.getName());
            ExchangeOrderTypeEnum salesOrderTypeEnum = ExchangeOrderTypeEnum.of(t.getSalesOrderType());
            Optional.ofNullable(salesOrderTypeEnum).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "订单类型编码"));
            // 覆盖用户传入数据
            t.setSalesOrderTypeName(salesOrderTypeEnum.getDesc());
            if(StringUtils.isNotBlank(t.getOrderChannelCode())) {
                OrderChannelEnum orderChannelEnum = OrderChannelEnum.of(t.getOrderChannelCode());
                Optional.ofNullable(orderChannelEnum).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "订单渠道编码"));
                t.setOrderChannelName(orderChannelEnum.getDesc());
            }

            SalesOrderDeliveryMethodEnum salesOrderDeliveryMethodEnum = SalesOrderDeliveryMethodEnum.of(t.getDeliveryMethodCode());
            Optional.ofNullable(salesOrderDeliveryMethodEnum).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "配送方式编码"));
            // 覆盖用户传入数据
            t.setDeliveryMethodName(salesOrderDeliveryMethodEnum.getDesc());

            if (StringUtils.isNotBlank(t.getOrderReasonCode())) {
                SalesOrderReasonEnum salesOrderReasonEnum = SalesOrderReasonEnum.of(t.getOrderReasonCode());
                Optional.ofNullable(salesOrderReasonEnum).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "订单原因编码"));
            }

            // 校验扩展字段是否为JSON格式
            AssertUtils.isTrue(!JsonUtils.isValidJson(t.getBizFeatures()), "OC-00-001-01-15-001", "扩展字段");

            for (ExchangeOrderLineAtomCreateRequest p : t.getOrderDetails()) {
                StockUnitEnum salesUnit = StockUnitEnum.of(p.getSalesUnitCode());
                StockUnitEnum stockUnit = StockUnitEnum.of(p.getStockUnitCode());
                Optional.ofNullable(salesUnit).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "销售单位编码"));
                Optional.ofNullable(stockUnit).orElseThrow(() -> new FunctionException("OC-01-001-01-15-006", "库存单位编码"));

                // 覆盖用户传入数据
                p.setSalesUnitName(salesUnit.getDesc());
                p.setStockUnitName(stockUnit.getDesc());

                // 校验扩展字段是否为JSON格式
                AssertUtils.isTrue(!JsonUtils.isValidJson(p.getBizFeatures()), "OC-00-001-01-15-001", "扩展字段");
            }
        });
    }

    @Override
    public void paramsNotBlankCheck(List<ExchangeOrderAtomCreateRequest> requestList, List<OrderAtomCreateResponse> responseList) {
        AssertUtils.isTrue(CollectionUtils.isEmpty(requestList), "OC-01-001-01-15-001", "单据列表");
        AssertUtils.isTrue(requestList.size() > 100, "OC-01-001-01-15-004", "单据列表", requestList.size(), "100");
        requestList.forEach(t -> {
            // 必填校验
            AssertUtils.isTrue(StringUtils.isBlank(t.getFromSys()), "OC-01-001-01-15-001", "来源系统编码");
            AssertUtils.isTrue(StringUtils.isBlank(t.getBusinessType()), "OC-01-001-01-15-001", "业态编码");
            AssertUtils.isTrue(StringUtils.isBlank(t.getBusinessUnitCode()), "OC-01-001-01-15-001", "业务单元编码");
            AssertUtils.isTrue(StringUtils.isBlank(t.getSourceOrderNo()), "OC-01-001-01-15-001", "来源单号");
            AssertUtils.isTrue(StringUtils.isBlank(t.getExpectedDeliveryDate()), "OC-01-001-01-15-001", "期望交货日期");

            //AssertUtils.isTrue(StringUtils.isBlank(t.getPreOrderNo()), "OC-01-001-01-15-001", "业务单元编码");
            AssertUtils.isTrue(StringUtils.isBlank(t.getBusinessUnitCode()), "OC-01-001-01-15-001", "业务单元编码");
            //AssertUtils.isTrue(Objects.isNull(t.getIsSubmit()), "OC-01-001-01-15-001", "是否提交");
            AssertUtils.isTrue(StringUtils.isBlank(t.getSalesOrderType()), "OC-01-001-01-15-001", "订单类型编码");
            // AssertUtils.isTrue(StringUtils.isBlank(t.getOrderChannelCode()), "OC-01-001-01-15-001", "订单渠道编码");
            //AssertUtils.checkRequired(Pair.of(t.getSalesOrderType(), t.getSalesOrderTypeName()), "OC-01-001-01-15-001", "订单类型编码、名称");
            AssertUtils.checkRequired(Pair.of(t.getCustomerCode(), t.getCustomerName()), "OC-01-001-01-15-001", "客户售达方编码、名称");
            AssertUtils.checkRequired(Pair.of(t.getShipToPartyCode(), t.getShipToPartyName()), "OC-01-001-01-15-001", "客户送达方编码、名称");
            AssertUtils.checkRequired(Pair.of(t.getBusinessChannel(), t.getBusinessChannelName()), "OC-01-001-01-15-001", "业务渠道编码、名称");
            AssertUtils.checkRequired(Pair.of(t.getSalesOrganizationCode(), t.getSalesOrganizationName()), "OC-01-001-01-15-001", "销售组织编码、名称");
            AssertUtils.checkRequired(Pair.of(t.getProductGroupCode(), t.getProductGroupName()), "OC-01-001-01-15-001", "产品组编码、名称");
            AssertUtils.isTrue(StringUtils.isBlank(t.getDeliveryMethodCode()), "OC-01-001-01-15-001", "配送方式编码");
            //AssertUtils.checkRequired(Pair.of(t.getDeliveryMethodCode(), t.getDeliveryMethodName()), "OC-01-001-01-15-001", "配送方式编码、名称");
            AssertUtils.checkRequired(Pair.of(t.getCreatorCode(), t.getCreatorName()), "OC-01-001-01-15-001", "创建人工号、姓名");

            AssertUtils.isTrue(CollectionUtils.isEmpty(t.getOrderDetails()), "OC-01-001-01-15-001", "单据明细");
            AssertUtils.isTrue(t.getOrderDetails().size() > 100, "OC-01-001-01-15-004", "单据明细", t.getOrderDetails().size(), "100");
            t.getOrderDetails().forEach(detail -> {
                AssertUtils.isTrue(StringUtils.isBlank(detail.getSourceLineNum()), "OC-01-001-01-15-001", "来源单行号");
                AssertUtils.isTrue(StringUtils.isBlank(detail.getProductQuantity()), "OC-01-001-01-15-001", "销售数量");
                AssertUtils.isTrue(StringUtils.isBlank(detail.getStockConversionNum()), "OC-01-001-01-15-001", "库存转换数量");
                AssertUtils.isTrue(StringUtils.isBlank(detail.getUnitConversionRelationship()), "OC-01-001-01-15-001", "单位转换关系");
                AssertUtils.checkRequired(Pair.of(detail.getProductCode(), detail.getProductName()), "OC-01-001-01-15-001", "物料编码、名称");
                AssertUtils.checkRequired(Pair.of(detail.getSalesUnitCode(), detail.getSalesUnitName()), "OC-01-001-01-15-001", "销售单位编码、名称");
                AssertUtils.checkRequired(Pair.of(detail.getStockUnitCode(), detail.getStockUnitName()), "OC-01-001-01-15-001", "库存单位编码、名称");

                // 非必填校验，若填写需保证成对存在
                AssertUtils.checkNotRequired(Pair.of(detail.getShippingWarehouseCode(), detail.getShippingWarehouseName()), "OC-01-001-01-15-001", "发货仓库编码、名称");
                AssertUtils.checkNotRequired(Pair.of(detail.getReceiveWarehouseCode(), detail.getReceiveWarehouseName()), "OC-01-001-01-15-001", "收货仓库编码、名称");

                if (StringUtils.isBlank(detail.getShippingWarehouseCode())) {
                    if (StringUtils.isBlank(detail.getDeliveryFactoryCode()) && StringUtils.isBlank(detail.getStockCode())) {
                        throw new FunctionException("OC-01-001-01-15-010", "逻辑仓库编码、交货工厂编码、库存地点编码");
                    }
                    AssertUtils.isTrue(StringUtils.isBlank(detail.getDeliveryFactoryCode()), "OC-01-001-01-15-001", "交货工厂编码");
                    AssertUtils.isTrue(StringUtils.isBlank(detail.getStockCode()), "OC-01-001-01-15-001", "库存地点编码");
                }

                if (StringUtils.isBlank(detail.getReceiveWarehouseCode())) {
                    if (StringUtils.isBlank(detail.getReceiveFactoryCode()) && StringUtils.isBlank(detail.getReceiveStockCode())) {
                        throw new FunctionException("OC-01-001-01-15-010", "收货逻辑仓库编码、收货工厂编码、收货库存地点编码");
                    }
                    AssertUtils.checkNotRequired("OC-01-001-01-15-001", "收货工厂编码、收货库存地点编码", detail.getReceiveFactoryCode(), detail.getReceiveStockCode());
                }
            });

            // 明细行 收货工厂+收货库存地点唯一 or 收货逻辑仓库唯一
            List<String> receiveWarehouseCodes = t.getOrderDetails().stream().map(ExchangeOrderLineAtomCreateRequest::getReceiveWarehouseCode)
                    .filter(StringUtils::isNotBlank)
                    .distinct().collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(receiveWarehouseCodes) && receiveWarehouseCodes.size() > 1) {
                throw new FunctionException("OC-01-001-01-15-003", t.getSourceOrderNo(), StringUtils.join(receiveWarehouseCodes, ","));
            } else {
                List<String> tmpCodes = t.getOrderDetails().stream()
                        .filter(p -> StringUtils.isNotBlank(p.getReceiveFactoryCode()) && StringUtils.isNotBlank(p.getReceiveStockCode()))
                        .map(p -> String.format("%s_%s", p.getReceiveFactoryCode(), p.getReceiveStockCode()))
                        .distinct().collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(tmpCodes) && tmpCodes.size() > 1) {
                    throw new FunctionException("OC-01-001-01-15-003", t.getSourceOrderNo(), StringUtils.join(tmpCodes, ","));
                }
            }

            // 明细行号不能重复
            List<String> sameSourceLines = t.getOrderDetails().stream().map(ExchangeOrderLineAtomCreateRequest::getSourceLineNum)
                    .collect(Collectors.toMap(p -> p, p -> 1, Integer::sum))
                    .entrySet().stream().filter(entry -> entry.getValue() > 1)
                    .map(Map.Entry::getKey).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(sameSourceLines)) {
                throw new FunctionException("OC-01-001-01-15-002", "来源单行号", StringUtils.join(sameSourceLines, ","));
            }
        });

        // 重复数据校验 取出重复数据
        List<String> sameSourceOrderNos = requestList.stream().map(ExchangeOrderAtomCreateRequest::getSourceOrderNo)
                .collect(Collectors.toMap(t -> t, t -> 1, Integer::sum))
                .entrySet().stream().filter(entry -> entry.getValue() > 1)
                .map(Map.Entry::getKey).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(sameSourceOrderNos)) {
            throw new FunctionException("OC-01-001-01-15-002", "来源单号", StringUtils.join(sameSourceOrderNos, ","));
        }
    }

    @Override
    public void paramsLengthCheck(List<ExchangeOrderAtomCreateRequest> requestList, List<OrderAtomCreateResponse> responseList) {
        requestList.forEach(t -> {
            AssertUtils.isNumber(t.getBusinessType(), true, "OC-01-001-01-15-006", "业态编码");

            // 必填校验
            AssertUtils.lengthCheck(t.getFromSys(), 50, true, "OC-01-001-01-15-004", "来源系统编码");
            AssertUtils.lengthCheck(t.getBusinessType(), 10, true, "OC-01-001-01-15-004", "业态编码");
            AssertUtils.lengthCheck(t.getBusinessUnitCode(), 50, true, "OC-01-001-01-15-004", "业务单元编码");
            AssertUtils.lengthCheck(t.getSourceOrderNo(), 50, true, "OC-01-001-01-15-004", "来源单号");
            AssertUtils.lengthCheck(t.getPreOrderNo(), 50, false, "OC-01-001-01-15-004", "业务单元编码");
            AssertUtils.lengthCheck(t.getOriginalOrderNo(), 50, false, "OC-01-001-01-15-004", "原销售订单单号");
            AssertUtils.lengthCheck(t.getCustomerPurchaseOrderNo(), 50, false, "OC-01-001-01-15-004", "客户采购订单号");

            AssertUtils.lengthCheck(t.getSalesOrderType(), 10, true, "OC-01-001-01-15-004", "订单类型编码");
            AssertUtils.lengthCheck(t.getSalesOrderTypeName(), 50, false, "OC-01-001-01-15-004", "订单类型名称");
            AssertUtils.lengthCheck(t.getCustomerCode(), 50, true, "OC-01-001-01-15-004", "客户售达方编码");
            AssertUtils.lengthCheck(t.getCustomerName(), 50, true, "OC-01-001-01-15-004", "客户售达方名称");
            AssertUtils.lengthCheck(t.getShipToPartyCode(), 50, true, "OC-01-001-01-15-004", "客户送达方编码");
            AssertUtils.lengthCheck(t.getShipToPartyName(), 50, true, "OC-01-001-01-15-004", "客户送达方名称");
            AssertUtils.lengthCheck(t.getBusinessChannel(), 50, true, "OC-01-001-01-15-004", "业务渠道编码");
            AssertUtils.lengthCheck(t.getBusinessChannelName(), 50, true, "OC-01-001-01-15-004", "业务渠道名称");
            AssertUtils.lengthCheck(t.getSalesOrganizationCode(), 50, true, "OC-01-001-01-15-004", "销售组织编码");
            AssertUtils.lengthCheck(t.getSalesOrganizationName(), 50, true, "OC-01-001-01-15-004", "销售组织名称");
            AssertUtils.lengthCheck(t.getProductGroupCode(), 50, true, "OC-01-001-01-15-004", "产品组编码");
            AssertUtils.lengthCheck(t.getProductGroupName(), 50, true, "OC-01-001-01-15-004", "产品组名称");
            AssertUtils.lengthCheck(t.getDeliveryMethodCode(), 50, true, "OC-01-001-01-15-004", "配送方式编码");
            AssertUtils.lengthCheck(t.getDeliveryMethodName(), 50, false, "OC-01-001-01-15-004", "配送方式名称");
            AssertUtils.lengthCheck(t.getCreatorCode(), 50, true, "OC-01-001-01-15-004", "创建人工号");
            AssertUtils.lengthCheck(t.getCreatorName(), 50, true, "OC-01-001-01-15-004", "创建人姓名");

            // 非必填校验，若填写需保证成对存在
            AssertUtils.lengthCheck(t.getSalesChannelCode(), 50, false, "OC-01-001-01-15-004", "销售渠道编码");
            AssertUtils.lengthCheck(t.getSalesChannelName(), 50, false, "OC-01-001-01-15-004", "销售渠道名称");
            AssertUtils.lengthCheck(t.getSalesDepartmentCode(), 50, false, "OC-01-001-01-15-004", "销售部门编码");
            AssertUtils.lengthCheck(t.getSalesDepartmentName(), 50, false, "OC-01-001-01-15-004", "销售部门名称");
            AssertUtils.lengthCheck(t.getCostCenterCode(), 50, false, "OC-01-001-01-15-004", "成本中心编码");
            AssertUtils.lengthCheck(t.getCostCenterName(), 50, false, "OC-01-001-01-15-004", "成本中心名称");
            AssertUtils.lengthCheck(t.getOrderReasonCode(), 32, false, "OC-01-001-01-15-004", "订单原因编码");
            AssertUtils.lengthCheck(t.getNote(), 255, false, "OC-01-001-01-15-004", "订单头备注");
            AssertUtils.lengthCheck(t.getCashCustomerName(), 50, false, "OC-01-001-01-15-004", "一次性客户名称");

            AssertUtils.lengthCheck(t.getExpectedDeliveryDate(), 10, true, "OC-01-001-01-15-004", "期望交货日期");
            AssertUtils.lengthCheck(t.getCustomerPurchaseDate(), 10, false, "OC-01-001-01-15-004", "客户采购订单日期");
            AssertUtils.lengthCheck(t.getOrderChannelCode(), 50, false, "OC-01-001-01-15-004", "订单渠道编码");

            AssertUtils.lengthCheck(t.getBizFeatures(), 1024, false, "OC-01-001-01-15-004", "扩展字段");

            // 日期格式校验
            AssertUtils.isTrue(!DateUtils.isDateFormat(t.getExpectedDeliveryDate()), "OC-01-001-01-15-001", "期望交货日期");
            AssertUtils.isTrue(DateUtils.formatDate(new Date()).compareTo(t.getExpectedDeliveryDate()) > 0, "OC-01-001-01-16-021");
            if (StringUtils.isNotBlank(t.getCustomerPurchaseDate())) {
                AssertUtils.isTrue(!DateUtils.isDateFormat(t.getCustomerPurchaseDate()), "OC-01-001-01-15-001", "客户采购订单日期");
            }

            t.getOrderDetails().forEach(detail -> {
                AssertUtils.isWholeNumber(detail.getProductQuantity(), true, "OC-01-001-01-15-001", "销售数量");
                AssertUtils.isNumber(detail.getStockConversionNum(), true, "OC-01-001-01-15-001", "库存转换数量");
                AssertUtils.isNumber(detail.getUnitPrice(), false, "OC-01-001-01-15-001", "常规单价");
                AssertUtils.isNumber(detail.getTotalAmount(), false, "OC-01-001-01-15-001", "常规总金额");
                AssertUtils.isNumber(detail.getManualTotalAmount(), false, "OC-01-001-01-15-001", "手工总金额");
                AssertUtils.isNumber(detail.getManualPrice(), false, "OC-01-001-01-15-001", "手工单价");
                AssertUtils.isNumber(detail.getActivityPrice(), false, "OC-01-001-01-15-001", "活动单价");
                AssertUtils.isNumber(detail.getActivityTotalAmount(), false, "OC-01-001-01-15-001", "活动总金额");
                AssertUtils.isNumber(detail.getUnitConversionRelationship(), false, "OC-01-001-01-15-001", "单位转换关系");

                AssertUtils.lengthCheck(detail.getSourceLineNum(), 10, true, "OC-01-001-01-15-004", "来源单行号");
                AssertUtils.lengthCheck(detail.getProductCode(), 50, true, "OC-01-001-01-15-004", "物料编码");
                AssertUtils.lengthCheck(detail.getProductName(), 50, true, "OC-01-001-01-15-004", "物料名称");
                AssertUtils.lengthCheck(detail.getProductQuantity(), 10, true, "OC-01-001-01-15-004", "销售数量");
                AssertUtils.lengthCheck(detail.getStockConversionNum(), 10, true, "OC-01-001-01-15-004", "库存转换数量");
                AssertUtils.lengthCheck(detail.getSalesUnitCode(), 50, true, "OC-01-001-01-15-004", "销售单位编码");
                AssertUtils.lengthCheck(detail.getSalesUnitName(), 50, true, "OC-01-001-01-15-004", "销售单位名称");
                AssertUtils.lengthCheck(detail.getStockUnitCode(), 50, true, "OC-01-001-01-15-004", "库存单位编码");
                AssertUtils.lengthCheck(detail.getStockUnitName(), 50, true, "OC-01-001-01-15-004", "库存单位名称");
                AssertUtils.lengthCheck(detail.getUnitPrice(), 50, false, "OC-01-001-01-15-004", "常规单价");
                AssertUtils.lengthCheck(detail.getTotalAmount(), 50, false, "OC-01-001-01-15-004", "常规总金额");
                AssertUtils.lengthCheck(detail.getUnitConversionRelationship(), 50, true, "OC-01-001-01-15-004", "单位转换关系");

                AssertUtils.isTrue(new BigDecimal("2147483647").compareTo(new BigDecimal(detail.getProductQuantity())) < 0, "OC-01-001-01-15-006", "销售数量", "最大2147483647");
                AssertUtils.isTrue(BigDecimal.ZERO.compareTo(new BigDecimal(detail.getProductQuantity())) >= 0, "OC-01-001-01-15-006", "销售数量", "不允许为零或负数");
                AssertUtils.isTrue(BigDecimal.ZERO.compareTo(new BigDecimal(detail.getStockConversionNum())) >= 0, "OC-01-001-01-15-006", "库存转换数量", "不允许为零或负数");
                AssertUtils.isTrue(BigDecimal.ZERO.compareTo(new BigDecimal(detail.getUnitConversionRelationship())) >= 0, "OC-01-001-01-15-006", "单位转换关系", "不允许为零或负数");

                AssertUtils.lengthCheck(detail.getInnerProductCode(), 50, false, "OC-01-001-01-15-004", "产品编码");
                AssertUtils.lengthCheck(detail.getInnerProductName(), 50, false, "OC-01-001-01-15-004", "产品名称");
                AssertUtils.lengthCheck(detail.getProductBarCode(), 50, false, "OC-01-001-01-15-004", "产品条码");
                AssertUtils.lengthCheck(detail.getNote(), 255, false, "OC-01-001-01-15-004", "订单行备注");
                AssertUtils.lengthCheck(detail.getActivityPrice(), 50, false, "OC-01-001-01-15-004", "活动单价");
                AssertUtils.lengthCheck(detail.getActivityTotalAmount(), 50, false, "OC-01-001-01-15-004", "活动总金额");
                AssertUtils.lengthCheck(detail.getActivityType(), 50, false, "OC-01-001-01-15-004", "活动类型");
                AssertUtils.lengthCheck(detail.getActivityId(), 50, false, "OC-01-001-01-15-004", "活动ID");
                AssertUtils.lengthCheck(detail.getActivityLineNo(), 50, false, "OC-01-001-01-15-004", "活动项目号");
                AssertUtils.lengthCheck(detail.getGiftFlag(), 50, false, "OC-01-001-01-15-004", "买赠标识");
                AssertUtils.lengthCheck(detail.getBuyItemNo(), 50, false, "OC-01-001-01-15-004", "原品行号");
                AssertUtils.lengthCheck(detail.getManualTotalAmount(), 10, false, "OC-01-001-01-15-004", "手工总金额");
                AssertUtils.lengthCheck(detail.getManualPrice(), 50, false, "OC-01-001-01-15-004", "手工单价");

                AssertUtils.lengthCheck(detail.getShippingWarehouseCode(), 50, false, "OC-01-001-01-15-004", "发货仓库编码");
                AssertUtils.lengthCheck(detail.getShippingWarehouseName(), 50, false, "OC-01-001-01-15-004", "发货仓库名称");
                AssertUtils.lengthCheck(detail.getDeliveryFactoryCode(), 50, false, "OC-01-001-01-15-004", "交货工厂编码");
                AssertUtils.lengthCheck(detail.getDeliveryFactoryName(), 50, false, "OC-01-001-01-15-004", "交货工厂名称");
                AssertUtils.lengthCheck(detail.getStockCode(), 50, false, "OC-01-001-01-15-004", "发货库存地点编码");
                AssertUtils.lengthCheck(detail.getStockName(), 50, false, "OC-01-001-01-15-004", "发货库存地点名称");

                AssertUtils.lengthCheck(detail.getReceiveWarehouseCode(), 50, false, "OC-01-001-01-15-004", "收货仓库编码");
                AssertUtils.lengthCheck(detail.getReceiveWarehouseName(), 50, false, "OC-01-001-01-15-004", "收货仓库名称");
                AssertUtils.lengthCheck(detail.getReceiveFactoryCode(), 50, false, "OC-01-001-01-15-004", "收货工厂编码");
                AssertUtils.lengthCheck(detail.getReceiveFactoryName(), 50, false, "OC-01-001-01-15-004", "收货工厂名称");
                AssertUtils.lengthCheck(detail.getReceiveStockCode(), 50, false, "OC-01-001-01-15-004", "收货库存地点编码");
                AssertUtils.lengthCheck(detail.getReceiveStockName(), 50, false, "OC-01-001-01-15-004", "收货库存地点名称");
                AssertUtils.lengthCheck(detail.getProductionDate(), 10, false, "OC-01-001-01-15-004", "生产日期");
                if (StringUtils.isNotBlank(detail.getProductionDate())) {
                    AssertUtils.isTrue(!DateUtils.isDateFormat(detail.getProductionDate()), "OC-01-001-01-15-001", "生产日期");
                }
                AssertUtils.lengthCheck(detail.getBizFeatures(), 1024, false, "OC-01-001-01-15-004", "扩展字段");

                // 金额参数 不允许为零或负数
                AssertUtils.moneyCheck(detail.getUnitPrice(), false, "OC-01-001-01-15-005", "常规单价");
                AssertUtils.moneyCheck(detail.getTotalAmount(), false, "OC-01-001-01-15-005", "常规总金额");
                AssertUtils.moneyCheck(detail.getManualTotalAmount(), false, "OC-01-001-01-15-005", "手工总金额");
                AssertUtils.moneyCheck(detail.getManualPrice(), false, "OC-01-001-01-15-005", "手工单价");
                AssertUtils.moneyCheck(detail.getActivityPrice(), false, "OC-01-001-01-15-005", "活动单价");
                AssertUtils.moneyCheck(detail.getActivityTotalAmount(), false, "OC-01-001-01-15-005", "活动总金额");
                // 金额 NYC(元) 1.01 转 数据库(分) 101
                resetMoneyForNYC(detail);
            });
        });
    }

    /**
     * 金额转换 元转分
     */
    static void resetMoneyForNYC(ExchangeOrderLineAtomCreateRequest request) {
        request.setUnitPrice(MoneyUtils.moneyStrYuan2Fen(request.getUnitPrice()));
        request.setTotalAmount(MoneyUtils.moneyStrYuan2Fen(request.getTotalAmount()));
        request.setManualPrice(MoneyUtils.moneyStrYuan2Fen(request.getManualPrice()));
        request.setManualTotalAmount(MoneyUtils.moneyStrYuan2Fen(request.getManualTotalAmount()));
        request.setActivityPrice(MoneyUtils.moneyStrYuan2Fen(request.getActivityPrice()));
        request.setActivityTotalAmount(MoneyUtils.moneyStrYuan2Fen(request.getActivityTotalAmount()));
    }
}
